package cn.shopping.core.service.impl;

import cn.shopping.common.bo.PageBO;
import cn.shopping.common.dto.PageQueryItemDTO;
import cn.shopping.common.dto.QueryItemDTO;
import cn.shopping.common.exception.CommonErrorCode;
import cn.shopping.common.exception.CommonException;
import cn.shopping.common.util.CommonUtils;
import cn.shopping.common.util.DaoUtils;
import cn.shopping.core.daomanager.GoodsDaoManager;
import cn.shopping.core.daomanager.GoodsFileDaoManager;
import cn.shopping.core.daomanager.UploadInfoDaoManager;
import cn.shopping.core.daomanager.UploadInfoImgDaoManager;
import cn.shopping.core.dbo.GoodsDO;
import cn.shopping.core.dbo.GoodsFileDO;
import cn.shopping.core.dto.*;
import cn.shopping.core.enums.FileTypeEnum;
import cn.shopping.core.service.GoodsService;
import cn.shopping.core.vo.GoodsVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

/**
 * 描述:
 *
 * @author Zhanggq
 * @date 2019/4/4 16:13
 */
@Service
public class GoodsServiceImpl implements GoodsService {

    public static final Integer APT_FORM_INPUT_ERROR = 100001;
    @Autowired
    private GoodsDaoManager goodsDaoManager;

    @Autowired
    private GoodsFileDaoManager goodsFileDaoManager;

    @Autowired
    private UploadInfoDaoManager uploadInfoDaoManager;

    @Autowired
    private UploadInfoImgDaoManager uploadInfoImgDaoManager;


    /**
     * 新增商品
     *
     * @param dto
     * @return
     */
    @Override
    @Transactional
    public Long insertGoods(GoodsDTO dto) {
        this._checkGoods(dto);
        //保存信息
        return this._saveGoods(dto).getId();
    }

    @Override
    public GoodsDTO getGoodsByGoodsId(Long goodsId) {
        return this._getAptFormDTO(this.goodsDaoManager.getById(goodsId));
    }

    @Override
    @Transactional
    public Integer deleteGoodsByIds(DeleteGoodsIdDTO dto) {
        this.goodsFileDaoManager.deleteByInClfGoodsId(dto.getGoodsIdList());
        return this.goodsDaoManager.deleteByIds(dto.getGoodsIdList());
    }

    @Override
    public PageBO<GoodsVO> pageListGoods(PageListGoodsDTO dto) {
        List<QueryItemDTO> itemList = new ArrayList<>();
        if (!StringUtils.isBlank(dto.getDescribe())) {//商品描述
            itemList.add(DaoUtils.buildLike(GoodsDO.DESCRIBE, "%" + dto.getDescribe() + "%"));
        }
        if (!StringUtils.isBlank(dto.getTitle())) {
            itemList.add(DaoUtils.buildLike(GoodsDO.TITLE, "%" + dto.getTitle() + "%"));
        }

        if (!Objects.isNull(dto.getId())) {
            itemList.add(DaoUtils.buildEqualTo(GoodsDO.ID, dto.getId()));
        }
        if (!Objects.isNull(dto.getPrice())) {
            itemList.add(DaoUtils.buildEqualTo(GoodsDO.PRICE, dto.getPrice()));
        }
        if (!Objects.isNull(dto.getStartTime())) {//申请时间起
            itemList.add(DaoUtils.buildGreaterThenOrEqualTo(GoodsDO.GMT_CREATE, dto.getStartTime()));
        }
        if (!Objects.isNull(dto.getEndTime())) {//申请时间止
            itemList.add(DaoUtils.buildLessThenOrEqualTo(GoodsDO.GMT_CREATE, dto.getEndTime()));
        }
        PageQueryItemDTO pageQueryItemDTO = CommonUtils.newInstance(dto, PageQueryItemDTO.class);
        pageQueryItemDTO.setQueryItems(itemList);
        if (StringUtils.isBlank(pageQueryItemDTO.getSortFieldName())) {
            pageQueryItemDTO.setSortFieldName(GoodsDO.GMT_MODIFIED);
            pageQueryItemDTO.setSortType("DESC");
        }
        PageBO<GoodsDO> goodsDOPageBO = this.goodsDaoManager.pageQuery(pageQueryItemDTO);
        List<GoodsDO> goodsDOS = goodsDOPageBO.getList();
        return CommonUtils.convertPageBO(goodsDOPageBO, goodsDO -> {
            return CommonUtils.newInstance(goodsDO, GoodsVO.class);
        });
    }

    @Override
    @Transactional
    public Long updateGoodsById(UpdateGoodsDTO dto) {
        GoodsDO goodsDO = null;
        if (!Objects.isNull(dto) && !Objects.isNull(dto.getId())) {
            goodsDO = this.goodsDaoManager.getById(dto.getId());
        }
        if (Objects.isNull(goodsDO)) {
            throw CommonException.exception(CommonErrorCode.PARAM_ERROR_CODE, "该商品不存在");
        }
        goodsDO = CommonUtils.newInstance(dto, GoodsDO.class);
        goodsDaoManager.updateNotNullProperties(goodsDO);
        return goodsDO.getId();
    }

    public GoodsDO _saveGoods(GoodsDTO dto) {
        //先处理goods表的数据
        //根据dto里的id，在数据库中找，没找到就新增，有找到就保存
        GoodsDO goodsDO = null;
        if (dto.getId() != null) {
            goodsDO = this.goodsDaoManager.getById(dto.getId());
        }
        if (goodsDO == null) {
            //不存在
            goodsDO = CommonUtils.newInstance(dto, GoodsDO.class);
            this.goodsDaoManager.insertAllProperties(goodsDO);
        } else {
            //不存在
            throw CommonException.exception(CommonErrorCode.PARAM_ERROR_CODE, "该商品已经存在");
        }
        Long goodsDOId = goodsDO.getId();
        //再处理goods_file表数据
        if (!CollectionUtils.isEmpty(dto.getFileList())) {
            //使用给定的初始值创建一个新的AtomicLong
            AtomicLong seq = new AtomicLong(10L);
            List<GoodsFileDO> goodsFileDOList = CommonUtils.collection2List(dto.getFileList(), goodsFileDTO -> {
                GoodsFileDO goodsFileDO = CommonUtils.newInstance(goodsFileDTO, GoodsFileDO.class);
                goodsFileDO.setClfGoodsId(goodsDOId);
                goodsFileDO.setSeq(seq.incrementAndGet());
                return goodsFileDO;
            });
            this.goodsFileDaoManager.insertAllPropertiesList(goodsFileDOList);
        }
        return goodsDO;
    }

    private void _checkGoods(GoodsDTO dto) {
        List<GoodsFileDTO> fileList = dto.getFileList();
        if (CollectionUtils.isEmpty(fileList)) {
            throw CommonException.exception(APT_FORM_INPUT_ERROR, "带红色*号项位置必须上传图片文件");
        }
        List<Integer> fileTypeList = fileList.stream().map(GoodsFileDTO::getFileType).collect(Collectors.toList());
        if (!fileTypeList.contains(FileTypeEnum.GOODS_Z.getCode())) {
            throw CommonException.exception(APT_FORM_INPUT_ERROR, String.format("[%s]必须上传", FileTypeEnum.GOODS_Z.getDesc()));
        }
        if (!fileTypeList.contains(FileTypeEnum.GOODS_F.getCode())) {
            throw CommonException.exception(APT_FORM_INPUT_ERROR, String.format("[%s]必须上传", FileTypeEnum.GOODS_F.getDesc()));
        }
    }


    protected GoodsDTO _getAptFormDTO(GoodsDO goodsDO) {
        if (goodsDO == null) {
            return null;
        }
        //拿到所有的上传附件
        List<GoodsFileDO> goodsFileDOS = this.goodsFileDaoManager.listByClfGoodsId(goodsDO.getId());
        GoodsDTO goodsDTO = CommonUtils.newInstance(goodsDO, GoodsDTO.class);
        //这里copy的时候已经写明，{@linkplain AptFormFileDTO#uploadId 文件上传后返回的ID}即是{@linkplain AptFormFileDO#uploadId }
        goodsDTO.setFileList(CommonUtils.collection2List(goodsFileDOS, goodsFileDO -> CommonUtils.newInstance(goodsFileDO, GoodsFileDTO.class)));
        return goodsDTO;
    }

}
